﻿//==============================================================================
// File: ShellAnimationController.cs
// Created: 2010-06-07
// Author: Piotr Włodek, Arkadiusz Świerczek
//==============================================================================
// This file is a part of MAMMOTH project.
// Copyright (C) 2010 AGH University of Science and Technology, Krakow.
// https://caribou.iisg.agh.edu.pl/trac/mammoth
//
// Mammoth is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Mammoth is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with Mammoth. If not, see http://www.gnu.org/licenses/.
//==============================================================================

using System;
using System.ComponentModel;
using System.Windows;
using WpfRcp.Controls;
using WpfRcp.Core.Services;
using WpfRcp.Core.Views;
using Microsoft.Practices.ServiceLocation;

namespace WpfRcp.Core.Common.Behaviors
{
    /// <summary>
    /// Persists a Window's Size, Location and WindowState to UserScopeSettings 
    /// </summary>
    public class WindowSettingsBehavior
    {
        #region Constructor

        private readonly Window m_Window;

        public WindowSettingsBehavior(Window window)
        {
            m_Window = window;
        }

        #endregion

        #region Attached "Save" Property Implementation

        /// <summary>
        /// Register the "Save" attached property and the "OnSaveInvalidated" callback 
        /// </summary>
        public static readonly DependencyProperty SaveProperty
            = DependencyProperty.RegisterAttached("Save", typeof(bool), typeof(WindowSettingsBehavior),
                                                  new FrameworkPropertyMetadata(new PropertyChangedCallback(OnSaveInvalidated)));

        public static void SetSave(DependencyObject dependencyObject, bool enabled)
        {
            dependencyObject.SetValue(SaveProperty, enabled);
        }

        /// <summary>
        /// Called when Save is changed on an object.
        /// </summary>
        private static void OnSaveInvalidated(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            var window = dependencyObject as Window;
            if (window != null)
            {
                if ((bool)e.NewValue)
                {
                    var settings = new WindowSettingsBehavior(window);
                    settings.Attach();
                }
            }
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// Load the Window Size Location and State from the settings object
        /// </summary>
        protected virtual void LoadWindowState()
        {
            var settingsService = ServiceLocator.Current.GetInstance<ISettingsService>();
            var settings = settingsService.GetViewSettings<ViewSettings>(m_Window.GetType());

            if (settings.IsNew == false)
            {
                m_Window.Height = settings.Height;
                m_Window.Width = settings.Width;
                m_Window.Top = settings.Top;
                m_Window.Left = settings.Left;

                if (m_Window is ChromeWindow)
                {
                    ((ChromeWindow)m_Window).IsMaximized = settings.IsMaximized;
                }
                else
                {
                    m_Window.WindowState = settings.IsMaximized ? WindowState.Maximized : WindowState.Normal;
                }
            }
        }

        /// <summary>
        /// Save the Window Size, Location and State to the settings object
        /// </summary>
        protected virtual void SaveWindowState()
        {
            var settingsService = ServiceLocator.Current.GetInstance<ISettingsService>();
            var settings = settingsService.GetViewSettings<ViewSettings>(m_Window.GetType());

            settings.IsMaximized = m_Window.WindowState == WindowState.Maximized;
            settings.Height = m_Window.Height;
            settings.Width = m_Window.Width;
            settings.Top = m_Window.Top;
            settings.Left = m_Window.Left;
            settings.IsNew = false;
        }

        #endregion

        #region Private Methods

        private void Attach()
        {
            if (m_Window != null)
            {
                m_Window.Closing += ClosingHandler;
                m_Window.Loaded += LoadedHandler;
            }
        }

        private void LoadedHandler(object sender, RoutedEventArgs e)
        {
            LoadWindowState();
        }

        private void ClosingHandler(object sender, CancelEventArgs e)
        {
            SaveWindowState();
        }

        #endregion
    }
}